package org.compiere.dsr;

/**
 * @author E.Maimanov
 * 
 * This class generates 2-dimension array-report from BPM_Form Settings
 */

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.adempiere.exceptions.AdempiereException;
import org.compiere.model.MBPMForm;
import org.compiere.model.MBPMFormCell;
import org.compiere.model.MBPMFormColumn;
import org.compiere.model.MBPMFormLine;
import org.compiere.model.MBPMFormValues;
import org.compiere.util.Env;

public class DSR_DataCollection
{
	@SuppressWarnings("unused")
	private static final long serialVersionUID = 4320055593999100229L;
	
	public ArrayList<DSR_Row> elementData = new ArrayList<DSR_Row>();
	public DSR_Row header;
	public MBPMForm form;
	public int BPM_Project_ID;
	public int AD_Org_ID;
	public int AD_Client_ID;
	public Timestamp AggrTime;
	public boolean isOrderBy = false;
	public List<String>  RowHeader = new ArrayList<String>();
	
	public DSR_DataCollection(int BPM_Form_ID, int BPM_Project_ID, int AD_Org_ID, 
			int AD_Client_ID, Timestamp Created) 
	{
		form = new MBPMForm(Env.getCtx(), BPM_Form_ID, null);
		this.BPM_Project_ID = BPM_Project_ID;
		this.AD_Client_ID = AD_Client_ID;
		this.AD_Org_ID = AD_Org_ID;
		this.AggrTime=Created;
		this.isOrderBy = form.isOrderBy();
		for (int i=0; i<form.getTabLevel();i++) {
			switch (i) {
			  case 0: RowHeader.add(form.getWebParam1()); break;  	
			  case 1: RowHeader.add(form.getWebParam2()); break;  	
			  case 2: RowHeader.add(form.getWebParam3()); break;  	
			  case 3: RowHeader.add(form.getWebParam4()); break;  	
			  case 4: RowHeader.add(form.getWebParam5()); break;  	
			};	  
		}
		setHeader(0);
		setStruct(false, 0);
	}
	
	public DSR_DataCollection(int BPM_Form_ID, int BPM_Project_ID, int AD_Org_ID, 
			int AD_Client_ID) 
	{
		form = new MBPMForm(Env.getCtx(), BPM_Form_ID, null);
		this.BPM_Project_ID = BPM_Project_ID;
		this.AD_Client_ID = AD_Client_ID;
		this.AD_Org_ID = AD_Org_ID;
		for (int i=0; i<form.getTabLevel();i++) {
			switch (i) {
			  case 0: RowHeader.add(form.getWebParam1()); break;  	
			  case 1: RowHeader.add(form.getWebParam2()); break;  	
			  case 2: RowHeader.add(form.getWebParam3()); break;  	
			  case 3: RowHeader.add(form.getWebParam4()); break;  	
			  case 4: RowHeader.add(form.getWebParam5()); break;  	
			};	  
		}
		setHeader(0);
		setStruct(false, 0);
	}
	
	public DSR_DataCollection(int BPM_Form_ID, int BPM_Project_ID, int AD_Org_ID, 
			int AD_Client_ID, int C_Year_ID) 
	{
		form = new MBPMForm(Env.getCtx(), BPM_Form_ID, null);
		this.BPM_Project_ID = BPM_Project_ID;
		this.AD_Client_ID = AD_Client_ID;
		this.AD_Org_ID = AD_Org_ID;
		for (int i=0; i<form.getTabLevel();i++) {
			switch (i) {
			  case 0: RowHeader.add(form.getWebParam1()); break;  	
			  case 1: RowHeader.add(form.getWebParam2()); break;  	
			  case 2: RowHeader.add(form.getWebParam3()); break;  	
			  case 3: RowHeader.add(form.getWebParam4()); break;  	
			  case 4: RowHeader.add(form.getWebParam5()); break;  	
			};	  
		}
		setHeader(C_Year_ID);
		setStruct(false, C_Year_ID);
	}
	
	public DSR_Row getHeader()
	{
		return header;
	}
	
	public DSR_Row getRow(int index)
	{
		if(index >= 0 && index < elementData.size())
			return elementData.get(index);
		else
			return null;
	}
	
	public int size()
	{
		return elementData.size();
	}
	
	/**
	 * Get header of current report
	 * Header is a set of column's name
	 * First row in elementData (index = 0)
	 */
	private void setHeader(int C_Year_ID)
	{
		MBPMFormColumn[] columns = null;
		
		if(C_Year_ID > 0)
			columns = MBPMFormColumn.getLineFormCode(Env.getCtx(), form.getBPM_FormCode_ID(), C_Year_ID, null);
		else
			columns = MBPMFormColumn.getLineFormCode(Env.getCtx(), form.getBPM_FormCode_ID(), null);
		
		header = new DSR_Row();
		
		DSR_Cell nullCell = new DSR_Cell("", "", null);
		nullCell.setHeader(true);
		header.add(nullCell);
			
		for(MBPMFormColumn column : columns)
		{
			DSR_Cell cell = new DSR_Cell(column.getName(), "", null);
			cell.setHeader(true);
			cell.LevelIndex = -1;
			cell.Alignment = 1;
			cell.VerticalAlignment = 1;
			cell.isBold = true;
			cell.Formula=column.getFormula();
			header.add(cell);
		}
	}
	
	/**
	 * Get values for current report
	 * and store them in elementData ArrayList<DSR_Row>()
	 */
	private void setStruct(boolean isStruct, int C_Year_ID)
	{		
		MBPMFormLine[] lines = MBPMForm.getLines(Env.getCtx(), form.get_ID(), null);
		MBPMFormColumn[] columns = null;
		if(C_Year_ID > 0)
			columns = MBPMFormColumn.getLineFormCode(Env.getCtx(), form.getBPM_FormCode_ID(), C_Year_ID, null);
		else
			columns = MBPMFormColumn.getLineFormCode(Env.getCtx(), form.getBPM_FormCode_ID(), null);
		
		MBPMFormCell cellBP = null;
		
		
		for(MBPMFormLine row : lines)
		{
			DSR_Row dsrRow = new DSR_Row();

			DSR_Cell rowCell = new DSR_Cell("", row.getName(), null);
			rowCell.setBPM_FormColumn_ID(0);
			rowCell.setBPM_FormLine_ID(row.get_ID());
			rowCell.setRow(true);
			rowCell.C_Charge_ID = row.getC_Charge_ID();
			rowCell.RowNumber = row.getV_Number();
			rowCell.LevelIndex= row.getTabLevel();
			dsrRow.add(rowCell);
			
			for(MBPMFormColumn column : columns) {
				
				cellBP = MBPMFormCell.getCell(Env.getCtx(), column.get_ID(), row.get_ID(), null);
				if(cellBP == null)
					throw new AdempiereException(String.format("No cell for column {0} and row {1}", column.getName(), row.getName()));

				String value = "";
				Integer BPM_FormValues_ID=0;
				Timestamp Updated=null;
				Properties values=null;
				if(!isStruct) {
					values = MBPMFormValues.getCellValues(row.get_ID(), column.get_ID(), BPM_Project_ID, AD_Org_ID, AD_Client_ID);
					if (values.size()>0) {
						if (values.getProperty("CellValue")!=null)
							value=values.getProperty("CellValue"); 
						if (values.getProperty("BPM_FormValues_ID")!=null)
							BPM_FormValues_ID=Integer.valueOf(values.getProperty("BPM_FormValues_ID"));
						else BPM_FormValues_ID=0;
						if (values.getProperty("Updated")!=null)
							Updated=Timestamp.valueOf(values.getProperty("Updated"));
					}	
				}	
				DSR_Cell cell = new DSR_Cell(null, null, value);
				cell.setBPM_FormValues_ID(BPM_FormValues_ID);
				cell.setBPM_FormColumn_ID(column.get_ID());
				cell.setBPM_FormLine_ID(row.get_ID());				
				cell.setBPM_FormCell_ID(cellBP.get_ID());
				cell.Alignment = (short) Integer.parseInt(cellBP.getAlignment());
				cell.VerticalAlignment = (short) Integer.parseInt(cellBP.getVerticalAlignment());
				cell.isBold = cellBP.isBold();
				cell.DataType = cellBP.getBPM_DataType();
				if ((Updated!=null)&&(AggrTime!=null)&&(Updated.after(AggrTime)))
					cell.Changed = true;
				if(!isStruct) {
					cell.Formula = cellBP.getFormula();
				} else {
					cell.Formula = column.getFormula();
				}
				if (AD_Org_ID==0) {
					if ((values.size()>0)&&(BPM_FormValues_ID>0))
						cell.Changed = true;
					else cell.Changed = false;	
					cell.Formula="0";
				}
				if (AD_Org_ID==1000007) {
					if ((values.size()>0)&&(BPM_FormValues_ID>0))
						cell.Changed = true;
					else cell.Changed = false;	
					cell.Formula=null;
				}
				
				dsrRow.add(cell);
			}

			elementData.add(dsrRow);
		}
	}
	
	public String toString()
	{
		int size = this.size();
		int cellSize = 0;
		
		StringBuilder builder = new StringBuilder();
		
		DSR_Row header = this.getHeader();
		
		builder.append(header);
		builder.append("\n");
		
		for(int i = 0; i < size; i++)
		{			
			DSR_Row row = this.getRow(i);
			cellSize = row.size();
			
			for(int j = 0; j < cellSize; j++)
			{
				DSR_Cell cell = row.getCell(j);
				
				String formatValue = String.format("%-20s", cell.getValue());
				
				builder.append(formatValue);
			}
			
			builder.append("\n");
		}
		
		return builder.toString();
	}
}
